package com.bwie.shop.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;

import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.common.utils.PageUtils;
import com.bwie.common.utils.Query;

import com.bwie.shop.dao.ShopDao;
import com.bwie.shop.entity.ShopEntity;
import com.bwie.shop.service.ShopService;


@Service("shopService")
public class ShopServiceImpl extends ServiceImpl<ShopDao, ShopEntity> implements ShopService {
//    @SuppressWarnings("all")
    @Autowired
    private RestHighLevelClient client;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<ShopEntity> wrapper = new QueryWrapper<>();
       
        String sname = (String) params.get("sname");
        if (!sname.isEmpty()){
            wrapper.and(w->{
               w.like("sname",sname);
            });
        }
        String ifnot = (String) params.get("ifnot");
        if (!ifnot.isEmpty()){
            wrapper.and(w->{
                w.eq("ifnot",ifnot);
            });
        }
        String cid = (String) params.get("cid");
        if (!cid.isEmpty()){
            wrapper.and(w->{
                w.eq("cid",cid);
            });
        }
        IPage<ShopEntity> page = this.page(
                new Query<ShopEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    //sname 高亮 来源名称cid
    @Override
    public PageUtils esQueryPage(Map<String, Object> params) throws IOException {
        List<ShopEntity> list2 = baseMapper.selectList(null);
        if (list2!=null){
            BulkRequest request = new BulkRequest();
            for (ShopEntity shopEntity : list2) {
                IndexRequest request2 = new IndexRequest("lastmonth");
                request2.id(shopEntity.getSid()+"");
                String jsonString = JSON.toJSONString(shopEntity);
                request2.source(jsonString, XContentType.JSON);
                request.add(request2);
            }
            BulkResponse bulkResponse = client.bulk(request, RequestOptions.DEFAULT);

        }
        //搜索
        SearchRequest searchRequest = new SearchRequest("lastmonth");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        String size = (String) params.get("limit");
        String page = (String) params.get("page");
        String sname = (String) params.get("sname");
        String cid = (String) params.get("cid");
        if (StringUtils.isNotEmpty(sname)){
            boolQueryBuilder.must(QueryBuilders.matchQuery("sname",sname));
        }
        if (StringUtils.isNotEmpty(cid)){
            boolQueryBuilder.must(QueryBuilders.termQuery("cid",Integer.parseInt(cid)));
        }
        searchSourceBuilder.from((Integer.parseInt(page)-1)*Integer.parseInt(size));
        searchSourceBuilder.size(Integer.parseInt(size));
        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder().field("sname");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlighter(highlightBuilder);

        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();
        TotalHits totalHits = hits.getTotalHits();
// the total number of hits, must be interpreted in the context of totalHits.relation
        long numHits = totalHits.value;
// whether the number of hits is accurate (EQUAL_TO) or a lower bound of the total (GREATER_THAN_OR_EQUAL_TO)
        TotalHits.Relation relation = totalHits.relation;
        float maxScore = hits.getMaxScore();
        ArrayList<ShopEntity> list = new ArrayList<>();
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            // do something with the SearchHit
            String index = hit.getIndex();
            String id = hit.getId();
            float score = hit.getScore();
            String sourceAsString = hit.getSourceAsString();
            ShopEntity shopEntity = JSON.parseObject(sourceAsString, new TypeReference<ShopEntity>() {
            });
            shopEntity.setSid(Integer.parseInt(id));

            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                HighlightField highlight = highlightFields.get("sname");
                if (highlight!=null){
                    Text[] fragments = highlight.fragments();
                    String fragmentString = fragments[0].string();
                    shopEntity.setSname(fragmentString);
                }

                list.add(shopEntity);
        }
        return new PageUtils(list, (int) numHits,Integer.parseInt(size),Integer.parseInt(page));
    }

    @Override
    public void qi(ShopEntity shop) {
        baseMapper.qi(shop);
    }

}